package com.mall.seckill_mall.service.impl;

import com.mall.seckill_mall.common.OrderStatus;
import com.mall.seckill_mall.common.RedisPreffix;
import com.mall.seckill_mall.dao.OrderDao;
import com.mall.seckill_mall.entity.Goods;
import com.mall.seckill_mall.entity.Order;
import com.mall.seckill_mall.entity.User;
import com.mall.seckill_mall.enums.CodeMessage;
import com.mall.seckill_mall.exception.UserException;
import com.mall.seckill_mall.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private RedisTemplate<String, Serializable> redisTemplate;

    @Override
    @Transactional
    public String createOrder(String userId, Goods goods) {
        String orderId = userId.concat("_").concat(goods.getGoodsId());
        Order order = new Order();
        order.setOrderId(orderId);
        order.setUserId(userId);
        order.setGoodsId(goods.getGoodsId());
        order.setOrderCreateTime(new Date());
        order.setOrderGoodsCount(1);
        order.setOrderPrice(goods.getGoodsPrice());
        order.setOrderStatus(OrderStatus.HAVE_NOT_PAID);
        String orderKey = RedisPreffix.ORDER_PREFFIX.concat(orderId);
        redisTemplate.opsForValue().set(orderKey, order);
        orderDao.insertOne(order);
        return orderId;
    }

    @Override
    public Order getOrder(String userToken, String goodsId) {
        User user = (User) redisTemplate.opsForValue().get(RedisPreffix.ONLINE_USER_PREFFIX.concat(userToken));
        if(user == null) {
            throw new UserException(CodeMessage.PLEASE_LOGIN);
        }
        String orderKey = RedisPreffix.ORDER_PREFFIX.concat(user.getUserId()).concat("_").concat(goodsId);
        Order order = (Order)redisTemplate.opsForValue().get(orderKey);
        if(order == null) {
            order = orderDao.selectByUserAndGoods(user.getUserId(), goodsId);
            if(order != null) {
                redisTemplate.opsForValue().set(orderKey, order);
            }
        }
        return order;
    }

    @Override
    public Order getOrderByOrderId(String orderId) {
        String orderKey = RedisPreffix.ORDER_PREFFIX.concat(orderId);
        Order order = (Order) redisTemplate.opsForValue().get(orderKey);
        if(order == null) {
            order = orderDao.selectOne(orderId);
            if(order != null) {
                redisTemplate.opsForValue().set(orderKey, order);
            }
        }
        return order;
    }

    @Override
    @Transactional
    public void deleteOrder(String orderId) {
        String orderKey = RedisPreffix.ORDER_PREFFIX.concat(orderId);
        orderDao.deleteOne(orderId);
        redisTemplate.delete(orderKey);
    }

    @Override
    @Transactional
    public void updateOrderStatus(String orderId) {
        orderDao.updateOrderStatus(orderId, OrderStatus.HAVE_PAID);
        String orderKey = RedisPreffix.ORDER_PREFFIX.concat(orderId);
        Order order = (Order) redisTemplate.opsForValue().get(orderKey);
        if(order != null) {
            order.setOrderStatus(OrderStatus.HAVE_PAID);
            redisTemplate.opsForValue().set(orderKey, order, 1, TimeUnit.DAYS);
        }
    }
}
